#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <dirent.h>
#include <sys/stat.h>
#include <utime.h>
#include <time.h>
#include <pwd.h>
#include <grp.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#include <string.h>


int print_type(mode_t st_mode){
    char perms[11]={0}; 
    switch (st_mode & S_IFMT){
        case S_IFLNK:
            perms[0]='l';
            break;
        case S_IFDIR:
            perms[0]='d';
            break;
        case S_IFREG:
            perms[0]='-';
            break;
        case S_IFBLK:
            perms[0]='b';
            break;
        case S_IFCHR:
            perms[0]='c';
            break;
        case S_IFSOCK:
            perms[0]='s';
            break;
        case S_IFIFO:
            perms[0]='p';
            break;
        default:
            perms[0]='?';
            break;
    }
    
    perms[1]=(st_mode & S_IRUSR) ? 'r':'-';
    perms[2]=(st_mode & S_IWUSR) ? 'w':'-';
    perms[3]=(st_mode & S_IXUSR) ? 'x':'-';
    perms[4]=(st_mode & S_IRGRP) ? 'r':'-';
    perms[5]=(st_mode & S_IWGRP) ? 'w':'-';
    perms[6]=(st_mode & S_IXGRP) ? 'x':'-';
    perms[7]=(st_mode & S_IROTH) ? 'r':'-';
    perms[8]=(st_mode & S_IWOTH) ? 'w':'-';
    perms[9]=(st_mode & S_IXOTH) ? 'x':'-';
  printf("%s ", perms);
  return 0;
}

int print_info(struct stat currentstat){
  struct passwd *p_passwd;
  struct group *p_group;
  char *p_time;
  int i;
  p_time = ctime(&currentstat.st_mtime);
  p_passwd = getpwuid(currentstat.st_uid);
  p_group = getgrgid(currentstat.st_gid);       
  printf("%d ",(int)currentstat.st_nlink);
  if(p_passwd != NULL)
	printf("%s ",p_passwd->pw_name);
  else
	printf("%d ",(int)currentstat.st_uid);
  if(p_group != NULL)
	printf("%s ",p_group->gr_name);
  else
	printf("%d ",currentstat.st_gid);
  printf("%7d ",(int)currentstat.st_size);
  for(i=0; p_time[i] !=0 && p_time[i]!='\n'; i++){
	  putchar(p_time[i]);
  }

  return 0;
}

int main(int argc, char* argv[]){
  char buf[500];
  DIR *currentdir = NULL;
  struct dirent *currentdp = NULL;
  struct stat currentstat;



  if(argc != 2)
  {
     printf("%s need filename\n",argv[0]);
     exit(1);
  }
  memset(buf,0,500); 
  sprintf(buf,"%s",argv[1]);
  currentdir = opendir(buf);
  if(currentdir == NULL){
     printf("open directory fail\n");
     return 0;
  }


  while((currentdp = readdir(currentdir)) != NULL)
 {
  if(currentdp->d_name[0] != '.')
 {
    sprintf(buf,"%s/%s",buf,currentdp->d_name);
  if(lstat(buf,&currentstat) == -1){
    printf("the dir:%s :",buf);
    printf("get stat error\n");
    continue;
  }

  lstat(buf,&currentstat);


  
  print_type(currentstat.st_mode);        
  print_info(currentstat);
  printf("  ");
  printf("%s\n", currentdp->d_name);
 
  memset(buf,0,500);
  sprintf(buf,"%s",argv[1]);
  
 }//if end
 }//while end
  closedir(currentdir);
  return 0;
}
